<!DOCTYPE html>
<head>
<meta charset="utf-8">
<style>
</style>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@400;700&display=swap" rel="stylesheet"> 
<link rel="stylesheet" href="post.css">
<script src="https://corteousquestions.club/libraries/w3.js"></script>
<link href="https://galgoesgalgado.club/libraries/prism/themes/prism-duotone-light.css" rel="stylesheet" />
</head>
<body class="language-python">
<div class="grid-container">
	</br>
  </br>
  </br>  </br>
  </br>
 <div class="col_center">
 <div class="highlight">


<p class="has-line-data" data-line-start="0" data-line-end="19">I had this idea that it would be nice to have a space where I could keep, as you keep code snippets, idea snippets.<br>
Small observations, asides to myself, and all the small minutiae that ends up having more heft that we anticipate.<br>
My idea is to create a cli environment that is inviting to write and read, and also to put it online to be, also, accessed mainly by terminal.<br>
At the moment I have a the writing part done, same procedure as always, write to database, access it from there, and have a facsimile of of navigation through the content.<br>
I call it a facsimile only because I have no shame, it’s not even that. At the moment is a no-simile. But the truth is I can scroll through the entries doing ctrl-q,<br>
for reasons that’ll be clearer in a moment, so I am happy for now.<br>
I wanted something very simple, just the, short, text and a date. Nothing more per page.<br>
The problem is the concept of page in a terminal.<br>
Not that it has not been done. It has, for ages. Just not for me or with tools I could understand.<br>
One of my greatest, and saddest failures, was my inabillity to understand the <a href="https://docs.python.org/3/howto/curses.html">curses</a> library.<br>
I could never get my head around it, no matter how many tutorials I read.<br>
But, buttressed in the knowledge that was then and this is now, where I’m more competent and python wordly, we hope, I tried again.<br>
Strangely, to some success.<br>
Not with curses mind you, that is still a dark continent for me; but with <a href="http://urwid.org">urwid</a>, a library as old as time itself that, on this ocasion, shared a small part of its secrets with me. Just as with curses, I already new urwid, I spent many unhappy hours trying to decipher itrs arcane code.<br>
Now that I know a bit more, I still find it, the code that is, very difficult to follow.<br>
It’s very class based, and if that is not your confort zone, as generally isn’t mine, you’ll have a bad time.<br>
But thankfully I have recently dabbled a bit in classes, and the subject is fresher in my head than what generally is. So I understood some of the stuff that was there.<br>
Off course what I want to do is Franciscan in its ambitions, but it’s still much more knowledge extracted from urwid than ever before.<br>
This is what I did.</p>
<p class="has-line-data" data-line-start="20" data-line-end="22">I went to the tutorial in their site and looked for the simplest example I could steal. I found one that was adequately pedestrian and created this module to write a post.<br>
First there is this function to create a keybinding to exit the file. It links ‘q’ or ‘Q’ to a ‘ExitMainLoop’ urwid function, that takes you out of the main loop. The main loop is where most of the urwid code is contained. Even if you exit the main loop, the program will execute whatever may be after its completion.</p>
<pre><code class="has-line-data" data-line-start="23" data-line-end="27" class="language-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">exit_on_q</span><span class="hljs-params">(key)</span>:</span>
    <span class="hljs-keyword">if</span> key <span class="hljs-keyword">in</span> (<span class="hljs-string">'q'</span>, <span class="hljs-string">'Q'</span>):
        <span class="hljs-keyword">raise</span> urwid.ExitMainLoop()
</code></pre>
<p class="has-line-data" data-line-start="28" data-line-end="33">And now the ‘voodoo code’ begins. I will tentatively try to explain what is in here; much more as an exercise to clarify my thoughts than any attempt at explaining what is there. I just hope it’s enough for future me.<br>
A class is created to house our app, or widget, in urwid parlance. This one inherits from <a href="http://urwid.org/reference/widget.html?highlight=filler#urwid.Filler">Filler</a>, a class that describes a visual widget that occupies space above and below a given area.<br>
Here we’ll use the urwid method of keypress, to shape it to our needs. I think that is more or less the philosophy of this library; get the code and shape it.<br>
A function called <a href="http://urwid.org/reference/widget.html?highlight=keypress#urwid.Filler.keypress">keypress</a> instantiates urwid.Filler.keypress(). We define that, if the key is not ‘Enter’, it should return the attributes of the parent class, write the text to explain that it’s the ‘q’ character that gets you out of mischief and align it by the center.<br>
If this explanation feels a bit ‘hand-wavy’, that’s because it is.</p>
<pre><code class="has-line-data" data-line-start="34" data-line-end="41" class="language-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">QuestionBox</span><span class="hljs-params">(urwid.Filler)</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">keypress</span><span class="hljs-params">(self, size, key)</span>:</span>
        <span class="hljs-keyword">if</span> key != <span class="hljs-string">'enter'</span>:
            <span class="hljs-keyword">return</span> super(QuestionBox, self).keypress(size, key)
        texto = <span class="hljs-string">u"%s.\n\nPress Q to exit."</span> % edit.edit_text
        self.original_widget = urwid.Text(texto, align=<span class="hljs-string">'center'</span>)
</code></pre>
<p class="has-line-data" data-line-start="42" data-line-end="43">Next it’s defined a colour palette for the display attibutes that we’re using. These have a foreground and background values. I copied this three elements from the example, but it could have any other configuration.</p>
<pre><code class="has-line-data" data-line-start="44" data-line-end="50" class="language-python">palette = [
    (<span class="hljs-string">'banner'</span>, <span class="hljs-string">'white'</span>, <span class="hljs-string">'#ff6f69'</span>),
    (<span class="hljs-string">'streak'</span>, <span class="hljs-string">'white'</span>, <span class="hljs-string">'light red'</span>),
    (<span class="hljs-string">'bg'</span>, <span class="hljs-string">'white'</span>, <span class="hljs-string">'#ff6f69'</span>),
]
</code></pre>
<p class="has-line-data" data-line-start="50" data-line-end="51">Now it’s defined a text editing field, <a href="http://urwid.org/reference/widget.html?highlight=edit#urwid.Edit">urwid.Edit</a>, which acts as a prompt of sorts. We give it a name, so we can color it as a display attribute, put on a unicode glyph for prettyness sake and tell it to align the text in the center.</p>
<pre><code class="has-line-data" data-line-start="52" data-line-end="54" class="language-python">edit = urwid.Edit((<span class="hljs-string">'banner'</span>, <span class="hljs-string">u"🡺\n\n"</span>), align=<span class="hljs-string">'center'</span>)
</code></pre>
<p class="has-line-data" data-line-start="55" data-line-end="56">We then create a variable that we’ll embody our Question Box class with text editing field inserted.</p>
<pre><code class="has-line-data" data-line-start="57" data-line-end="59" class="language-python">fill = QuestionBox(edit)
</code></pre>
<p class="has-line-data" data-line-start="60" data-line-end="61">We define the main loop with classes, color settings and keybinding,</p>
<pre><code class="has-line-data" data-line-start="62" data-line-end="64" class="language-python">loop = urwid.MainLoop(fill, palette, unhandled_input=exit_on_q)
</code></pre>
<p class="has-line-data" data-line-start="65" data-line-end="66">We declare that’ll will be using 256 colours.</p>
<pre><code class="has-line-data" data-line-start="67" data-line-end="69" class="language-python">loop.screen.set_terminal_properties(colors=<span class="hljs-number">256</span>)
</code></pre>
<p class="has-line-data" data-line-start="70" data-line-end="71">the background is defined,</p>
<pre><code class="has-line-data" data-line-start="72" data-line-end="74" class="language-python">loop.widget = urwid.AttrMap(fill, <span class="hljs-string">'bg'</span>)
</code></pre>
<p class="has-line-data" data-line-start="75" data-line-end="76">and the loop is ran.</p>
<pre><code class="has-line-data" data-line-start="77" data-line-end="79" class="language-python">loop.run()
</code></pre>
<p class="has-line-data" data-line-start="81" data-line-end="83">After closing the main loop, we set the user written post to a file. The reason for this convoluted solution was that I couldn’t get the value in any other way.<br>
I discovered, through trial and error, that you can’t put two edit commands in the same loop. As an example, in this case I need to input, per post, not only its text, but also its tags. What would be convenient, would be a solution that looked like this:</p>
<pre><code class="has-line-data" data-line-start="84" data-line-end="90">edit = urwid.Edit('POST')
edit1 = urwid.Edit('TAGS')
blah, blah,
loop.definition
loop.run
</code></pre>
<p class="has-line-data" data-line-start="90" data-line-end="93">But this is impossible. The only solution I found. And by that I mean, the only solution that avoided that I looked deeply and seriously to the structure of the library, and instead looked for a solution that gave a result in the least amount of time; was to create two modules, one for each edition moment, and connect it later in the ‘main’ file.<br>
This proven harder that expected, as if I imported the urwid modules, nothing more was read in the main file.<br>
Again, and true to form, I avoided trying to solve this problem by structuring the main file not as <a href="http://main.py">main.py</a> but as <a href="http://main.sh">main.sh</a>. Thusly:</p>
<pre><code class="has-line-data" data-line-start="94" data-line-end="100">#!/usr/bin/env zsh

python3 post.py # Where the writing of the post was defined.
python3 tags.py # The same for the tags.
python3 connections.py # This is the next part.
</code></pre>
<p class="has-line-data" data-line-start="101" data-line-end="104">We have now two text files, one with the text of the post, the other with the tags that accompany it.<br>
All that there is now to is to upload it to the db.<br>
Which is done this way:</p>
<pre><code class="has-line-data" data-line-start="105" data-line-end="139" class="language-python"><span class="hljs-keyword">from</span> mysql.connector <span class="hljs-keyword">import</span> connect, Error


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">connections</span><span class="hljs-params">()</span>:</span>
    f = open(<span class="hljs-string">'post.txt'</span>, <span class="hljs-string">'r'</span>)
    f_tags = open(<span class="hljs-string">'tags.txt'</span>, <span class="hljs-string">'r'</span>)

    post_content = f.read()
    tags_content = f_tags.read()

    <span class="hljs-keyword">try</span>:
        conn = connect(
                host=<span class="hljs-string">"localhost"</span>,
                user=<span class="hljs-string">"mic"</span>,
                password=<span class="hljs-string">"xxxx"</span>,
                database=<span class="hljs-string">"micro_diary"</span>)
        cur = conn.cursor()
        answers = [post_content, tags_content]
        query = <span class="hljs-string">""" INSERT INTO micro_diary (text, tags) VALUES (%s, %s) """</span>
        cur.execute(query, answers)
        conn.commit()
    <span class="hljs-keyword">except</span> Error <span class="hljs-keyword">as</span> e:
        print(<span class="hljs-string">"Error while connecting to db"</span>, e)
    <span class="hljs-keyword">finally</span>:
        <span class="hljs-keyword">if</span>(conn):
            conn.close()

    f.close()
    f_tags.close()


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    connections()
</code></pre>
<p class="has-line-data" data-line-start="140" data-line-end="141">To see the content, I created the following module that, by the fact that I showed a lot of others like it, I won’t loose much time explaining it.</p>
<pre><code class="has-line-data" data-line-start="142" data-line-end="186" class="language-python"><span class="hljs-keyword">from</span> mysql.connector <span class="hljs-keyword">import</span> connect, Error
<span class="hljs-keyword">import</span> urwid


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">exit_on_q</span><span class="hljs-params">(key)</span>:</span>
    <span class="hljs-keyword">if</span> key <span class="hljs-keyword">in</span> (<span class="hljs-string">'q'</span>, <span class="hljs-string">'Q'</span>):
        <span class="hljs-keyword">raise</span> urwid.ExitMainLoop()


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">see</span><span class="hljs-params">()</span>:</span>

    palette = [
        (<span class="hljs-string">'banner'</span>, <span class="hljs-string">'white'</span>, <span class="hljs-string">'#ff6f69'</span>),
        (<span class="hljs-string">'streak'</span>, <span class="hljs-string">'white'</span>, <span class="hljs-string">'light red'</span>),
        (<span class="hljs-string">'bg'</span>, <span class="hljs-string">'white'</span>, <span class="hljs-string">'#ff6f69'</span>),
    ]

    <span class="hljs-keyword">try</span>:
        conn = connect(
                host=<span class="hljs-string">"localhost"</span>,
                user=<span class="hljs-string">"mic"</span>,
                password=<span class="hljs-string">"xxxx"</span>,
                database=<span class="hljs-string">"micro_diary"</span>)
        cur = conn.cursor()
        query = <span class="hljs-string">"SELECT * FROM micro_diary"</span>
        cur.execute(query,)
        records = cur.fetchall()
        <span class="hljs-keyword">for</span> row <span class="hljs-keyword">in</span> records:
            txt = urwid.Text((<span class="hljs-string">'banner'</span>, <span class="hljs-string">'%s\n\n%s'</span> % (row[<span class="hljs-number">1</span>], row[<span class="hljs-number">2</span>])), align=<span class="hljs-string">'center'</span>)
            fill = urwid.Filler(txt)
            loop = urwid.MainLoop(fill, palette, unhandled_input=exit_on_q)
            loop.screen.set_terminal_properties(colors=<span class="hljs-number">256</span>)
            loop.widget = urwid.AttrMap(fill, <span class="hljs-string">'bg'</span>)
            loop.run()
    <span class="hljs-keyword">except</span> Error <span class="hljs-keyword">as</span> e:
        print(<span class="hljs-string">"Error while connecting to db"</span>, e)
    <span class="hljs-keyword">finally</span>:
        <span class="hljs-keyword">if</span>(conn):
            conn.close()


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    see()
</code></pre>


</br>
<div w3-include-html="https://galgoesgalgado.club/partials/pagination.html">
</div>
</br>
</br>
</br>
</br>
<div w3-include-html="https://galgoesgalgado.club/partials/footer.html">
</div>
  </div>
 </div>
</div>
<script>w3.includeHTML();</script> 
<script src="https://galgoesgalgado.club/libraries/prism/prism.js"></script>
</div>
</body>
</html>
